from django.contrib.auth import login, authenticate, logout
from django.shortcuts import render
from django.views import View
from django.http import JsonResponse, HttpResponseBadRequest
from apps.users.models import User, Address
from django.conf import settings
import re
import json
import django_redis
from utils.views import LoginRequiredJsonMixin
import logging
from .utils import loads_email_token, dumps_email_token, cleck_token
from celery_tasks.emails.tasks import send_email
import pickle, base64
from django_redis import get_redis_connection

logger = logging.getLogger('django')
# Create your views here.

class UserPasswordUpdateView(LoginRequiredJsonMixin, View):
    def put(self, request):
        # 接受参数
        password_dict = json.loads(request.body.decode())
        old_password = password_dict.get('old_password')
        new_password = password_dict.get('new_password')
        new_password2 = password_dict.get('new_password2')

        # 效验参数
        # 校验参数
        if not all([old_password, new_password, new_password2]):
            return JsonResponse({'code': 400,
                                'errmsg': '缺少必传参数'})

        result = request.user.check_password(old_password)
        if not result:
            return JsonResponse({'code': 400,
                                'errmsg': '原始密码不正确'})

        if not re.match(r'^[0-9A-Za-z]{8,20}$', new_password):
            return JsonResponse({'code': 400,
                                'errmsg': '密码最少8位,最长20位'})

        if new_password != new_password2:
            return JsonResponse({'code': 400,
                                'errmsg': '两次输入密码不一致'})



        try:
            request.user.set_password(new_password)
            request.user.save()
        except Exception as e:
            logger.error(e)
            return HttpResponseBadRequest('失败')
        return JsonResponse({'code': 0,
                             'errmsg': 'ok'})


# ======================================================================================================

# 添加title
class UserAddressTitleView(LoginRequiredJsonMixin, View):
    def put(self, request, address_id):
        title_b = json.loads(request.body.decode())
        title = title_b.get('title')

        try:
            Address.objects.filter(id=address_id).update(title=title)
        except Address.DoesNotExist as e:
            logger.error(e)
            return HttpResponseBadRequest('添加失败')
        return JsonResponse({'code': 0,
                             'errmsg': 'ok'})


# ===============================================================================================================

# 设置默认地址
class UserAddressDefaultView(LoginRequiredJsonMixin, View):
    def put(self, request, address_id):
        try:
            User.objects.filter(id=request.user.id).update(default_address_id=address_id)
        except User.DoesNotExist as e:
            logger.error(e)
            return HttpResponseBadRequest('修改错误')
        return JsonResponse({'code': 0,
                             'errmsg': 'ok'})



# =================================================================================================================

# 地址增删改
class UserAddressModifyView(View):
    def delete(self, request, address_id):
        # 通过用户传来的address_id删除地址
        try:
            Address.objects.filter(id=address_id).delete()
        except Exception as e:
            logger.error(e)
            return HttpResponseBadRequest('删除失败')
        return JsonResponse({'code': 0,
                             'errmsg': 'ok'})

    def put(self, request, address_id):
        # 拿到修改后的数据
        json_dict = json.loads(request.body.decode())

        receiver = json_dict.get('receiver')
        province_id = json_dict.get('province_id')
        city_id = json_dict.get('city_id')
        district_id = json_dict.get('district_id')
        place = json_dict.get('place')
        mobile = json_dict.get('mobile')
        tel = json_dict.get('tel')
        email = json_dict.get('email')

        # 效验信息
        # 校验参数
        if not all([receiver, province_id, city_id, district_id, place, mobile]):
            return JsonResponse({'code': 400,
                                'errmsg': '缺少必传参数'})

        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return JsonResponse({'code': 400,
                                'errmsg': '参数mobile有误'})

        if tel:
            if not re.match(r'^(0[0-9]{2,3}-)?([2-9][0-9]{6,7})+(-[0-9]{1,4})?$', tel):
                return JsonResponse({'code': 400,
                                    'errmsg': '参数tel有误'})
        if email:
            if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
                return JsonResponse({'code': 400,
                                    'errmsg': '参数email有误'})
        # 用address_id查询数据库对象执行update
        try:
            address = Address.objects.filter(id=address_id)
            address.update(title=receiver,
                           receiver=receiver,
                           province=province_id,
                           city=city_id,
                           district=district_id,
                           place=place,
                           mobile=mobile,
                           tel=tel,
                           email=email
                           )
        except Address.DoesNotExist as e:
            logger.error(e)
            return HttpResponseBadRequest('修改失败')
        # 返回响应

        address = Address.objects.get(id=address_id)
        address_dict = {
            "id": address.id,
            "title": address.title,
            "receiver": address.receiver,
            "province": address.province.name,
            "city": address.city.name,
            "district": address.district.name,
            "place": address.place,
            "mobile": address.mobile,
            "tel": address.tel,
            "email": address.email
        }
        return JsonResponse({'code': 0,
                             'errmsg': 'ok',
                             'address': address_dict})


# =============================================================================================================

# 用户收货地址展示
class UserAddressLookView(LoginRequiredJsonMixin, View):
    def get(self, request):
        # 查询用户的收货地址
        try:
            address = Address.objects.filter(user=request.user,
                                             is_deleted=False)
        except Exception as e:
            logger.error(e)
            return HttpResponseBadRequest('查询错误')

        #　定义用户收货地址Ｌｉｓｔ
        user_address_list = []
        for user_address in address:
            user_address_dict = {
                "id": user_address.id,
                "title": user_address.title,
                "receiver": user_address.receiver,
                "province": user_address.province.name,
                "city": user_address.city.name,
                "district": user_address.district.name,
                "place": user_address.place,
                "mobile": user_address.mobile,
                "tel": user_address.tel,
                "email": user_address.email
            }
            # 如果是默认地址就放到list的最前面
            if request.user.default_address_id == user_address.id:
                user_address_list.insert(0, user_address_dict)
            else:
                user_address_list.append(user_address_dict)

        return JsonResponse({'code': 0,
                            'errmsg': 'ok',
                            'default_address_id': request.user.default_address_id,
                            'addresses': user_address_list})






# ===========================================================================================================

#　用户收货地址添加
class UserAddressAddView(LoginRequiredJsonMixin, View):
    def post(self, request):
        # 接受参数

        json_dict = json.loads(request.body.decode())
        receiver = json_dict.get('receiver')  # 收货人
        province_id = json_dict.get('province_id')  # 省份id
        city_id = json_dict.get('city_id')  # 城市id
        district_id = json_dict.get('district_id')  # 县区id
        place = json_dict.get('place')  # 收货地址
        mobile = json_dict.get('mobile')  # 电话号码
        tel = json_dict.get('tel')  # 固定电话
        email = json_dict.get('email')  # 邮箱

        # 效验参数
        if not all([receiver, province_id, city_id, district_id, place, mobile]):
            return JsonResponse({'code': 0,
                                 'errmsg': '参数缺失'})

        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return HttpResponseBadRequest('参数mobile有误')
        if tel:
            if not re.match(r'^(0[0-9]{2,3}-)?([2-9][0-9]{6,7})+(-[0-9]{1,4})?$', tel):
                return HttpResponseBadRequest('参数tel有误')
        if email:
            if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
                return HttpResponseBadRequest('参数email有误')

        # 保存参数
        try:
            address = Address.objects.create(user=request.user,
                                             receiver=receiver,
                                             province_id=province_id,
                                             city_id=city_id,
                                             district_id=district_id,
                                             place=place,
                                             mobile=mobile,
                                             tel=tel,
                                             email=email)




        except Exception as e:
            logger.error(e)
            return HttpResponseBadRequest('数据库保存不成功')

        else:
            if not request.user.default_address:
                # 设置为默认用户地址
                try:
                    request.user.default_address = address
                    request.user.save()
                except request.user.DoesNotExist:
                    return HttpResponseBadRequest('默认地址设置失败')

        # 返回数据给前端
        address_dict = {
            "id": address.id,
            "title": address.title,
            "receiver": address.receiver,
            "province": address.province.name,
            "city": address.city.name,
            "district": address.district.name,
            "place": address.place,
            "mobile": address.mobile,
            "tel": address.tel,
            "email": address.email
        }

        return JsonResponse({'code': 0, 'errmsg': '新增地址成功', 'address': address_dict})













# =================================================================================================================
# 激活邮件
class CleckUserEmailView(View):
    def put(self, request):
        # 获得token
        token = request.GET.get('token')

        # 验证token
        token_dict = cleck_token(token)

        if not token_dict:
            return JsonResponse({'code': 400,
                                'errmsg': '数据错误'})

        # 将email
        try:
            user = User.objects.get(pk=token_dict.get('user_id'), email=token_dict.get('emails'))
            user.email_active = True
            user.save()
        except User.DoesNotExist:
            return JsonResponse({'code': 400,
                                 'errmsg': '激活失败'})
        return JsonResponse({'code': 0,
                             'errmsg': 'ok'})
# ======================================================================================================

# 用户中心添加邮箱并发送邮件
class UserAddEmail(View):
    def put(self, request):
        # 拿到email
        body_data = json.loads(request.body.decode())
        email = body_data.get('email')
        # 效验数据
        if not email:
            return JsonResponse({'code': 400,
                                 'errmsg': '没有获得email'})
        if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
            return JsonResponse({'code': 400,
                                'errmsg': '参数email有误'})

        # 保存到数据库
        try:
            request.user.email = email
            request.user.save()
        except Exception as e:
            logger.error(e)
            return JsonResponse({'code': 400,
                                 'errmsg': '数据保存错误'})

        #return JsonResponse({'code': 0,
        #                    'errmsg': 'ok'})
        # 发送邮件逻辑
        token_dict = {'user_id': request.user.id,
                      'emails': request.user.email}
        # 加密
        token = dumps_email_token(token_dict)
        login_key_url = settings.EMAIL_VERIFY_URL + '?token=' + token
        # 发送email
        try:
            send_email.delay(email, login_key_url)
        except Exception as e:
            return JsonResponse({'code': 400,
                                 'errmsg': '发送失败'})
        return JsonResponse({'code': 0,
                            'errmsg': 'ok'})


# =============================================================================================================

# 用户中心
class UserInfoView(LoginRequiredJsonMixin, View):
    def get(self, request):
        info_data = {
            'username': request.user.username,
            'mobile': request.user.mobile,
            'email': request.user.email,
            'email_active': request.user.email_active
        }
        return JsonResponse({'code': 0,
                             'errmsg': 'ok',
                             'info_data': info_data})

# 退出登录
class UserLogoutView(View):
    def delete(self, request):
        # 清理sessoion
        logout(request)
        # 退出登录重定向到首页
        response = JsonResponse({'code': 0,
                                 'errmsg': 'ok'})
        # 删除cookie中的username
        response.delete_cookie('username')

        # 返回响应
        return response


# 用户登录
class UserLoginView(View):
    def post(self, request):
        # 拿到数据
        userinfo_dict = json.loads(request.body.decode())

        username = userinfo_dict.get('username')
        password = userinfo_dict.get('password')
        remember = userinfo_dict.get('remembered')

        # 效验数据(django提供的一个效验用户数据的方法)
        if not all([username, password]):
            return JsonResponse({'code': 400,
                                 'errmsg': '数据不全'})
            # 判断username or mobile
        if re.match('1[3-9]\d{9}', username):
            User.USERNAME_FIELD = 'mobile'

        # 如果存在返回用户，如果不存在返回None
        user = authenticate(username=username,
                            password=password)




        if user == None:
            return JsonResponse({'code': 400,
                                 'errmsg': '用户不存在'})

        # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        # 合并购物车
        cartsb_cookie = request.COOKIES.get('cartsb')
        if cartsb_cookie :

            cartsb_dict = pickle.loads(base64.b64decode(cartsb_cookie.encode()))

            redis_conn = get_redis_connection('carts')

            for sku_id, count_dict in cartsb_dict.items():
                count = count_dict['count']

                redis_conn.hincrby('cartsb_%s' % user.id, sku_id, count)

        # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++



        # 效验后操作
        login(request, user)
        if remember != True:
            request.session.set_expiry(0)
        else:
            request.session.set_expiry(None)

        # 返回数据 吧用户名写到cookie中

        response = JsonResponse({'code': 0,
                                'errmsg': 'ok'})
        response.set_cookie('username', user.username, max_age=2000)
        response.delete_cookie('cartsb')
        return response

# =======================================================================================================
# 用户注册
class UserRegister(View):

    def post(self, request):
        # 拿到数据
        user_dict = json.loads(request.body.decode())
        username = user_dict.get('username')
        password = user_dict.get('password')
        password2 = user_dict.get('password2')
        mobile = user_dict.get('mobile')
        sms_code = user_dict.get('sms_code')
        allow = user_dict.get('allow')
        # 补充注册效验用户的短信验证码
        # 拿到短信验证码
        redis_coun = django_redis.get_redis_connection('code')
        sms_code_server = redis_coun.get('sms_%s' % mobile)
        if sms_code_server is not None:
            sms_code_server = sms_code_server.decode()


        # 效验数据
        if not all([username, password, password2, mobile, sms_code, allow]):
            return JsonResponse({'code': 400,
                                 'errmsg': '数据不全'
                                 })
        if  sms_code_server == None:
            return JsonResponse({'code': 400,
                                 'errmsg': '验证码过期'})
        if sms_code_server != sms_code:
            return JsonResponse({'code': 400,
                                 'errmsg': '验证码不正确'})
        if not re.match(r'[a-zA-Z0-9_-]{5,20}', username):
            return JsonResponse({'code': 400,
                                 'errmsg': '用户名错误'
                                 })
        if not re.match(r'1[3-9]\d{9}', mobile):
            return   JsonResponse({'code': 400,
                                 'errmsg': '手机号不符合格式'
                                 })
        if not re.match(r'[0-9a-zA-Z]{8,20}', password):
            return  JsonResponse({'code': 400,
                                 'errmsg': '密码不符合格式'
                                 })
        if  password != password2:

            return JsonResponse({'code': 400,
                                 'errmsg': '密码不一致'
                                 })
        if allow != True:
            return JsonResponse({'code': 400,
                                 'errmsg': '未同意协议'
                                 })

        #效验成功后动作
        try:
            user = User.objects.create_user(username=username,
                                            password=password,
                                            mobile=mobile)
        except Exception as e:
            return JsonResponse({'code': 400,
                                 'errmsg': e
                                 })

        # 实现用户登录的状态保持
        login(request, user)

        return JsonResponse({'code': 0,
                                 'errmsg': 'ok'
                                 })

# =================================================================================================
# 定义用户重复注册的类视图

class UsernameCountView(View):

    def get(self, request, username):
        '''判断前端传来的用户名'''
        # 拿到用户数
        username_count = User.objects.filter(username=username).count()

        # 判断用户数是否是0
        if username_count == 0:
            return JsonResponse({'code': 0,
                                 'errmsg': 'ok',
                                 'count': username_count})
        return JsonResponse({'code': 400,
                             'errmsg': '用户名重复',
                             'count': username_count})


# ================================================================================================

# 定义用户手机号重复注册
class MobileCountView(View):

    def get(self, requset, mobile):
        '''判断用户手机号'''
        # 拿到相同手机号的用户数
        mobile_count = User.objects.filter(mobile=mobile).count()

        # 判断是否为0
        if mobile_count == 0:
            return JsonResponse({'code': 0,
                                 'errmsg': 'ok',
                                 'count': mobile_count})
        return JsonResponse({'code': 200,
                             'errmsg': '手机号重复',
                             'count': mobile_count})
